﻿using System;
using System.Linq;
using System.Windows;
using System.Windows.Input;
using ApiScannerShell.ViewModels;
using Microsoft.Win32;

namespace ApiScannerShell
{
    public sealed class MainViewModel : ViewModel<MainViewModel, MainModel>
    {
        public MainViewModel() : base(new MainModel())
        {
            AddSimpleMapping(v => v.FileName, () => string.IsNullOrEmpty(FileName) ? "The filename must be specified." : null);

            CloseCommand = new DelegateCommand(Close);
            OpenCommand = new DelegateCommand(Open);
            NewCommand = new DelegateCommand(New);
            SaveCommand = new DelegateCommand(() => Save());
            SaveAsCommand = new DelegateCommand(() => SaveAs());
            ExecuteTestsCommand = new DelegateCommand(CanExecuteExecuteTests, ExecuteExecuteTests);
           
            RegisterChildViewModels();
        }

        private void ExecuteExecuteTests()
        {
            //if (!Save()) return;
            Configuration.ExecuteTests();
        }

        private bool CanExecuteExecuteTests()
        {
            return Configuration.CanExecuteTests();
        }

        public ICommand CloseCommand { get; private set; }
        public ICommand OpenCommand { get; private set; }
        public ICommand NewCommand { get; private set; }
        public ICommand SaveCommand { get; private set; }
        public ICommand SaveAsCommand { get; private set; }
        public ICommand ExecuteTestsCommand { get; private set; }

        public string FileName
        {
            get { return GetValue(v => v.FileName); }
            set { SetValue(v => v.FileName, value); }
        }

        public ScannerConfigurationSectionViewModel Configuration
        {
            get { return GetChildViewModel(v => v.Configuration); }
        }

        private bool SaveAs()
        {
            var saveDialog = new SaveFileDialog
                                 {
                                     AddExtension = true,
                                     CheckPathExists = true,
                                     CreatePrompt = true,
                                     DereferenceLinks = true,
                                     Filter = "Config files (*.config)|*.config",
                                     OverwritePrompt = true,
                                     ValidateNames = true
                                 };
            if (!saveDialog.ShowDialog().GetValueOrDefault())
            {
                return false;
            }

            FileName = saveDialog.FileName;
            SaveValuesToModel();
            Model.SaveAs();
            return true;
        }

        public void Open()
        {
            var fileOpenDialog = new OpenFileDialog
                                     {
                                         CheckFileExists = true,
                                         DereferenceLinks = true,
                                         Filter = "Config files (*.config)|*.config"
                                     };

            if (!fileOpenDialog.ShowDialog().GetValueOrDefault()) return;
            var model = new MainModel(fileOpenDialog.FileName);
            Model = model;
            LoadValuesFromModel();
        }

        protected override void ModelChanged()
        {
            RegisterChildViewModels();
        }

        public override void LoadValuesFromModel()
        {
            RegisterChildViewModels();
            base.LoadValuesFromModel();
        }

        private void RegisterChildViewModels()
        {
            RegisterChildViewModel(v => v.Configuration, new ScannerConfigurationSectionViewModel(Model.Configuration));
        }

        private void New()
        {
            var model = new MainModel();
            Model = model;
            LoadValuesFromModel();
        }

        public bool Save()
        {
            if (string.IsNullOrEmpty(FileName))
            {
                return SaveAs();
            }
            SaveValuesToModel();
            Model.Save();
            return true;
        }

        private static void Close()
        {
            Application.Current.Shutdown();
        }
    }
}